﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ESGenerator {
    public class ClassGenerator {
        public static string PerformClass(Type typeEntity, string nameSpace) {
            string chaine = PerformImports();

            // Namespace
            chaine += "\nnamespace " + nameSpace + "\n";
            chaine += "{\n";

            // La classe
            chaine += "public class " + typeEntity.Name + "ES : AbstractES\n";
            chaine += "{\n";

            // Les proprietes
            foreach(PropertyInfo property in typeEntity.GetProperties()) {
                // On ignore les types spécifiques aux entities
                if(property.PropertyType.ToString().Contains("EntityReference") ||
                    property.PropertyType.ToString().Contains("EntityState") ||
                    property.PropertyType.ToString().Contains("EntityKey")) {
                    continue;
                }
                chaine += PerformProperty(property);
            }

            // Constructeur vide
            chaine += "public " + typeEntity.Name + "ES() { }\n";

            // Fin de fichier
            chaine += "}\n}";

            return chaine;
        }

        private static string PerformImports() {
            // Les imports
             string chaine = "using System;\n"
                + "using System.Collections.Generic;\n"
                + "using System.Text;\n"
                + "using GestionPedago.Services.Framework;\n";
             return chaine;
        }

        private static string PerformProperty(PropertyInfo property) {
            string chaine = "";
            string propertyTypeStr = property.PropertyType.ToString();
            string propertyNameStr = GetPropertyNameStr(property);

            propertyTypeStr = GetPropertyTypeStr(property);

            chaine += "public " + propertyTypeStr + " " + propertyNameStr + " { get; set; } \n";

            return chaine;
        }

        public static string GetPropertyTypeStr(PropertyInfo property) {
            string propertyTypeStr = property.PropertyType.ToString();

            // Prise en charge des types primitifs
            bool isArray = propertyTypeStr.Contains("[]");

            if(propertyTypeStr.Contains("System.Int16")) {
                propertyTypeStr = "short";
            } else if(propertyTypeStr.Contains("System.Int32")) {
                propertyTypeStr = "int";
            } else if(propertyTypeStr.Contains("System.Int64")) {
                propertyTypeStr = "long";
            } else if(propertyTypeStr.Contains("System.String")) {
                propertyTypeStr = "string";
            } else if(propertyTypeStr.Contains("System.Boolean")) {
                propertyTypeStr = "bool";
            } else if(propertyTypeStr.Contains("System.Double")) {
                propertyTypeStr = "double";
            } else if(propertyTypeStr.Contains("System.Byte")) {
                propertyTypeStr = "byte";
            } else if(propertyTypeStr.Contains("EntityCollection")) {// Types EntityCollection
                string[] str = propertyTypeStr.Substring(propertyTypeStr.IndexOf("[")).Replace("[", "").Replace("]", "").Split('.');
                propertyTypeStr = "List<" + str.Last() + "ES>";
            } else if(propertyTypeStr.Contains("EntityContext")) {// Types EntityContext
                propertyTypeStr = property.PropertyType.Name + "ES";
            } else if(propertyTypeStr.Contains("Nullable")) { // Types nullable
                propertyTypeStr = propertyTypeStr.Substring(propertyTypeStr.IndexOf("[")).Replace("[System.", "").Replace("]", "");
            } else { // Pour tous les autres types
                propertyTypeStr = property.PropertyType.Name;
            }

            if (isArray)
            {
                propertyTypeStr += "[]";
            }

            if(property.PropertyType.ToString().Contains("Nullable")) {
                propertyTypeStr += "?";
            }

            return propertyTypeStr;
        }

        public static string GetPropertyNameStr(PropertyInfo property) 
        {
            string propertyTypeStr = property.PropertyType.ToString();
            string propertyNameStr = property.Name;
            if(propertyTypeStr.Contains("EntityCollection")) {// Types EntityCollection
                propertyNameStr = "Liste" + propertyNameStr;
            }

            return propertyNameStr;
        }
    }
}
